package com.tnovoselec.android.nfc.record;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import android.nfc.NdefRecord;

import com.google.common.base.Preconditions;
import com.tnovoselec.android.nfc.ParsedNdefRecord;


public class TextRecord implements ParsedNdefRecord {

	/** ISO/IANA language code */
	private final String mLanguageCode;

	private final String mText;
	private final List<String> resultList = new ArrayList<String>(1);

	private TextRecord(String languageCode, String text) {
		mLanguageCode = Preconditions.checkNotNull(languageCode);
		mText = Preconditions.checkNotNull(text);
		resultList.add(mText);
	}

	public String getText() {
		return mText;
	}

	@Override
	public List<String> getContent() {
		return resultList;
	}

	/**
	 * Returns the ISO/IANA language code associated with this text element.
	 */
	public String getLanguageCode() {
		return mLanguageCode;
	}

	// TODO: deal with text fields which span multiple NdefRecords
	public static TextRecord parse(NdefRecord record) {
		Preconditions.checkArgument(record.getTnf() == NdefRecord.TNF_WELL_KNOWN);
		Preconditions.checkArgument(Arrays.equals(record.getType(), NdefRecord.RTD_TEXT));
		try {
			byte[] payload = record.getPayload();
			/*
			 * payload[0] contains the "Status Byte Encodings" field, per the
			 * NFC Forum "Text Record Type Definition" section 3.2.1.
			 *
			 * bit7 is the Text Encoding Field.
			 *
			 * if (Bit_7 == 0): The text is encoded in UTF-8 if (Bit_7 == 1):
			 * The text is encoded in UTF16
			 *
			 * Bit_6 is reserved for future use and must be set to zero.
			 *
			 * Bits 5 to 0 are the length of the IANA language code.
			 */
			String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";
			int languageCodeLength = payload[0] & 0077;
			String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
			String text = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);

			return new TextRecord(languageCode, text);
		} catch (UnsupportedEncodingException ex) {
			// should never happen unless we get a malformed tag.
			throw new IllegalArgumentException(ex);
		}
	}

	public static boolean isText(NdefRecord record) {
		try {
			TextRecord.parse(record);
			return true;
		} catch (IllegalArgumentException ex) {
			return false;
		}
	}
}
